package com.innovation.ic.sc.web.controller.sc;

import cn.hutool.core.lang.Validator;
import com.alibaba.fastjson.JSONObject;
import com.innovation.ic.b1b.framework.util.IpAddressUtil;
import com.innovation.ic.b1b.framework.util.StringUtils;
import com.innovation.ic.sc.base.pojo.constant.Constants;
import com.innovation.ic.sc.base.pojo.constant.LoginConstants;
import com.innovation.ic.sc.base.pojo.enums.LoginTypeEnum;
import com.innovation.ic.sc.base.pojo.variable.ApiResult;
import com.innovation.ic.sc.base.pojo.variable.ServiceResult;
import com.innovation.ic.sc.base.vo.login.*;
import com.innovation.ic.sc.web.controller.AbstractController;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

/**
 * @author linuo
 * @desc 登录controller
 * @time 2022年8月5日10:30:57
 */
@Api(value = "登录API", tags = "LoginController")
@RestController
@RequestMapping("/api/v1/login")
@DefaultProperties(defaultFallback = "defaultFallback")
public class LoginController extends AbstractController {
    private static final Logger log = LoggerFactory.getLogger(LoginController.class);

    /**
     * 通过短信验证码登录
     *
     * @return 返回登录结果
     */
    @HystrixCommand
    @ApiOperation(value = "通过短信验证码登录")
    @ApiImplicitParam(name = "smsLoginVo", value = "账号vo类", required = true, dataType = "SmsLoginVo")
    @RequestMapping(value = "/loginBySms", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> loginBySms(@RequestBody SmsLoginVo smsLoginVo, HttpServletRequest request, HttpServletResponse response) throws Exception {
        if (!StringUtils.validateParameter(smsLoginVo.getPhoneNum()) || !StringUtils.validateParameter(smsLoginVo.getCode())) {
            String message = "调用接口【/api/v1/login/loginBySms】时，参数mobile与smsCode不能为空";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // 判断当前手机号是否格式正确
        boolean judgeResult = Validator.isMobile(smsLoginVo.getPhoneNum());
        if (!judgeResult) {
            String message = "手机号格式有误";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // 通过短信验证码登录
        ServiceResult<JSONObject> serviceResult = loginService.loginBySms(smsLoginVo);
        //判断用户id是否返回
        if (serviceResult.getResult() != null && !StringUtils.isEmpty(serviceResult.getResult().getString(Constants.ID))) {
            //将账号信息存入登录日志表中
            String ipAddress = IpAddressUtil.getIpAddress(request);
            userLoginLogService.addUserLog(serviceResult.getResult().getString(Constants.USERNAME), ipAddress, LoginConstants.PHONE_LOGIN);
        }

        ApiResult<JSONObject> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 获取支付宝登录授权地址
     *
     * @return 返回支付宝登录授权地址
     */
    @HystrixCommand
    @ApiOperation(value = "获取支付宝登录授权地址")
    @ApiImplicitParam(name = "getAuthUrlVo", value = "获取授权地址的Vo类", required = true, dataType = "GetAuthUrlVo")
    @RequestMapping(value = "/getAlipayAuthUrl", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> getAlipayAuthUrl(@RequestBody GetAuthUrlVo getAuthUrlVo, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        if (!StringUtils.validateParameter(getAuthUrlVo.getRedirectUrl())) {
            String message = "调用接口【/api/v1/login/getAlipayAuthUrl】时，参数redirectUrl不能为空";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // 获取支付宝授权地址
        ServiceResult<String> serviceResult = loginService.getAlipayAuthUrl(getAuthUrlVo.getRedirectUrl());

        ApiResult<String> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 获取微信登录授权地址
     *
     * @return 返回微信登录授权地址
     */
    @HystrixCommand
    @ApiOperation(value = "获取微信登录授权地址")
    @ApiImplicitParam(name = "getAuthUrlVo", value = "获取授权地址的Vo类", required = true, dataType = "GetAuthUrlVo")
    @RequestMapping(value = "/getWechatAuthUrl", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> getWechatAuthUrl(@RequestBody GetAuthUrlVo getAuthUrlVo, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        if (!StringUtils.validateParameter(getAuthUrlVo.getRedirectUrl())) {
            String message = "调用接口【/api/v1/login/getWechatAuthUrl】时，参数redirectUrl不能为空";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // 获取微信登录授权地址
        ServiceResult<String> serviceResult = loginService.getWechatAuthUrl(getAuthUrlVo.getRedirectUrl());

        ApiResult<String> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 获取QQ登录授权地址
     *
     * @return 返回QQ登录授权地址
     */
    @HystrixCommand
    @ApiOperation(value = "获取QQ登录授权地址")
    @ApiImplicitParam(name = "getAuthUrlVo", value = "获取授权地址的Vo类", required = true, dataType = "GetAuthUrlVo")
    @RequestMapping(value = "/getQQAuthUrl", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> getQQAuthUrl(@RequestBody GetAuthUrlVo getAuthUrlVo, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        if (!StringUtils.validateParameter(getAuthUrlVo.getRedirectUrl())) {
            String message = "调用接口【/api/v1/login/getQQAuthUrl】时，参数redirectUrl不能为空";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // 获取QQ登录授权地址
        ServiceResult<String> serviceResult = loginService.getQQAuthUrl(getAuthUrlVo.getRedirectUrl());

        ApiResult<String> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 支付宝登录
     *
     * @return 返回登录结果及登录信息
     */
    @HystrixCommand
    @ApiOperation(value = "支付宝登录")
    @ApiImplicitParam(name = "alipayLoginVo", value = "账号vo类", required = true, dataType = "AlipayLoginVo")
    @RequestMapping(value = "/loginByAlipay", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> loginByAlipay(@RequestBody AlipayLoginVo alipayLoginVo, HttpServletRequest request, HttpServletResponse response) {
        if (!StringUtils.validateParameter(alipayLoginVo.getAuthCode())) {
            String message = "调用接口【/api/v1/login/loginByAlipay】时，参数authCode不能为空";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // 支付宝登录
        ServiceResult<JSONObject> serviceResult = loginService.loginByAlipay(alipayLoginVo.getAuthCode());

        //判断用户id是否返回
        if (serviceResult.getResult() != null && !StringUtils.isEmpty(serviceResult.getResult().getString(Constants.ID))) {
            //将账号信息存入登录日志表中
            String ipAddress = IpAddressUtil.getIpAddress(request);//获取ip
            userLoginLogService.addUserLog(serviceResult.getResult().getString(Constants.USERNAME), ipAddress, LoginConstants.AlIPAY_LOGIN);
        }


        ApiResult<JSONObject> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 微信登录
     *
     * @return 返回登录结果及登录信息
     */
    @HystrixCommand
    @ApiOperation(value = "微信登录")
    @ApiImplicitParam(name = "wechatLoginVo", value = "账号vo类", required = true, dataType = "WechatLoginVo")
    @RequestMapping(value = "/loginByWechat", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> loginByWechat(@RequestBody WechatLoginVo wechatLoginVo, HttpServletRequest request, HttpServletResponse response) {
        if (!StringUtils.validateParameter(wechatLoginVo.getAuthCode())) {
            String message = "调用接口【/api/v1/login/loginByWechat】时，参数authCode不能为空";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // 微信登录
        ServiceResult<JSONObject> serviceResult = loginService.loginByWechat(wechatLoginVo.getAuthCode());

        //判断用户id是否返回
        if (serviceResult.getResult() != null && !StringUtils.isEmpty(serviceResult.getResult().getString(Constants.ID))) {
            //将账号信息存入登录日志表中
            String ipAddress = IpAddressUtil.getIpAddress(request);//获取ip
            userLoginLogService.addUserLog(serviceResult.getResult().getString(Constants.USERNAME), ipAddress, LoginConstants.WECHAT_LOGIN);
        }

        ApiResult<JSONObject> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * QQ登录
     *
     * @return 返回登录结果及登录信息
     */
    @HystrixCommand
    @ApiOperation(value = "QQ登录")
    @ApiImplicitParam(name = "qqLoginVo", value = "账号vo类", required = true, dataType = "QQLoginVo")
    @RequestMapping(value = "/loginByQQ", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> loginByQQ(@RequestBody QQLoginVo qqLoginVo, HttpServletRequest request, HttpServletResponse response) {
        if (!StringUtils.validateParameter(qqLoginVo.getAuthCode())) {
            String message = "调用接口【/api/v1/login/loginByQQ】时，参数authCode不能为空";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // QQ登录
        ServiceResult<JSONObject> serviceResult = loginService.loginByQQ(qqLoginVo.getAuthCode());

        //判断用户id是否返回
        if (serviceResult.getResult() != null && !StringUtils.isEmpty(serviceResult.getResult().getString(Constants.ID))) {
            //将账号信息存入登录日志表中
            String ipAddress = IpAddressUtil.getIpAddress(request);//获取ip
            userLoginLogService.addUserLog(serviceResult.getResult().getString(Constants.USERNAME), ipAddress, LoginConstants.QQ_LOGIN);
        }

        ApiResult<JSONObject> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 绑定第三方账户
     *
     * @return 返回绑定结果
     */
    @HystrixCommand
    @ApiOperation(value = "绑定第三方账户")
    @ApiImplicitParam(name = "BandThirdAccountVo", value = "账号vo类", required = true, dataType = "BandThirdAccountVo")
    @RequestMapping(value = "/bindThirdAccount", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> bindThirdAccount(@RequestBody BindThirdAccountVo bindThirdAccountVo, HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 使用微信绑定账号
        if (bindThirdAccountVo.getType().equals(LoginTypeEnum.WECHAT.getCode().toString())) {
            if (!StringUtils.validateParameter(bindThirdAccountVo.getType())
                    || !StringUtils.validateParameter(bindThirdAccountVo.getUserName())
                    || !StringUtils.validateParameter(bindThirdAccountVo.getPassWord())
                    || !StringUtils.validateParameter(bindThirdAccountVo.getUnionID())
                    || !StringUtils.validateParameter(bindThirdAccountVo.getOpenID())) {
                String message = "绑定微信调用接口【/api/v1/login/bindThirdAccount】时，参数type、userName、passWord、unionID和openID不能为空";
                log.warn(message);
                ApiResult<Boolean> apiResult = new ApiResult<>();
                apiResult.setSuccess(Boolean.FALSE);
                apiResult.setCode(HttpStatus.BAD_REQUEST.value());
                apiResult.setMessage(message);
                return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
            }
        }


        // 使用QQ、支付宝绑定账号
        if (bindThirdAccountVo.getType().equals(LoginTypeEnum.ALIPAY.getCode().toString()) || bindThirdAccountVo.getType().equals(LoginTypeEnum.QQ.getCode().toString())) {
            if (!StringUtils.validateParameter(bindThirdAccountVo.getType())
                    || !StringUtils.validateParameter(bindThirdAccountVo.getUserName())
                    || !StringUtils.validateParameter(bindThirdAccountVo.getPassWord())
                    || !StringUtils.validateParameter(bindThirdAccountVo.getOpenID())) {
                String message = "绑定QQ、支付宝调用接口【/api/v1/login/bindThirdAccount】时，参数type、userName、passWord和openID不能为空";
                log.warn(message);
                ApiResult<Boolean> apiResult = new ApiResult<>();
                apiResult.setSuccess(Boolean.FALSE);
                apiResult.setCode(HttpStatus.BAD_REQUEST.value());
                apiResult.setMessage(message);
                return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
            }
        }

        // 绑定第三方账户
        ServiceResult<JSONObject> serviceResult = loginService.bindThirdAccount(bindThirdAccountVo);

        ApiResult<JSONObject> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 解绑第三方账户
     *
     * @return 返回解绑结果
     */
    @HystrixCommand
    @ApiOperation(value = "解绑第三方账户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "解绑账号类型(0 微信、1 QQ、3 支付宝)", required = true, dataType = "String"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "String")
    })
    @RequestMapping(value = "/unBindThirdAccount/{type}/{userId}", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> unBindThirdAccount(@PathVariable("type") String type, @PathVariable("userId") String userId, HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 使用微信绑定账号
        if (!StringUtils.validateParameter(type) || !StringUtils.validateParameter(userId)) {
            String message = "绑定微信调用接口【/api/v1/login/unBindThirdAccount】时，参数type和userId不能为空";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }


        // 解绑第三方账户
        ServiceResult<JSONObject> serviceResult = loginService.unBindThirdAccount(type, userId);

        ApiResult<JSONObject> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }
}